#!/bin/sh
# shellcheck disable=2164 disable=2046 disable=2034 disable=2012  disable=2120 disable=1091 disable=2181 disable=2140 disable=3045 disable=3002

USER_NAME=$(getent passwd $(who) | head -n 1 | cut -d : -f 1)
pwd=$(pwd)
smake="make install"

#一些颜色和格式常量
if which 'tput' >/dev/null; then
    if [ -t 1 ]; then
        ncolors=$(tput colors)
        if [ "$ncolors" -ge 8 ]; then
            RED=$(tput setaf 1)       #字体红色 31
            GREEN=$(tput setaf 2)     #字体绿色 32
            YELLOW=$(tput setaf 3)    #字体黄色 33
            BLUE=$(tput setaf 4)      #字体蓝色 34
            MAGENTA=$(tput setaf 5)   #字体紫色 35
            CYAN=$(tput setaf 6)      #字体青色 36
            WHITE=$(tput setaf 7)     #字体白色 37
            REDBG=$(tput setab 1)     #背景红色 41
            GREENBG=$(tput setab 2)   #背景绿色 42
            YELLOWBG=$(tput setab 3)  #背景黄色 43
            BLUEBG=$(tput setab 4)    #背景蓝色 44
            MAGENTABG=$(tput setab 5) #背景紫色 45
            CYANBG=$(tput setab 6)    #背景青色 46
            WHITEBG=$(tput setab 7)   #背景白色 47

            BOLD=$(tput bold)      #设置粗体 1
            UNDERLINE=$(tput smul) # 4设置下划线(模拟彩色显示器的颜色)许多终端不支持此功能
            NORMAL=$(tput sgr0)    #重新设置属性到缺省设置 0
        fi
    fi
else
    echo "$lang_tput."
    RED=''
    GREEN=''
    YELLOW=''
    BLUE=''
    MAGENTA=''
    CYAN=''
    WHITE=''
    REDBG=''
    GREENBG=''
    YELLOWBG=''
    BLUEBG=''
    MAGENTABG=''
    CYANBG=''

    BOLD=''
    UNDERLINE=''
    NORMAL=''
fi

info() {
    printf "%s${CYAN} $1 ${NORMAL}\n"
}

success() {
    printf "%s${GREEN} $1 ${NORMAL}\n"
}

error() {
    printf "%s${RED} $1 ${NORMAL}\n"
}

rmtmp() {
    DND="DO_NOT_DELETE"
    mkdir ${DND}
    mv "$DIST_DIR".tar.gz ${DND}
    mv aria2 ${DND}
    # shellcheck disable=2010
    ls -1A | grep -v ${DND} | xargs rm -rf
    cp -rf ${DND}/* . && rm -rf ${DND}
}

download() {
    package=$(echo "$1" | awk -F/ '{print $NF}')
    fname="${package%.tar*}"
    info "$lang_downin $package"
    curl -L -O "$1"
    if [ $? -ne 0 ]; then
        error "$lang_downer"
    else
        return 0
    fi
}

build_if() {
    if [ -f "$pwd"/"$package" ]; then
        tar xf "$package"
        if [ -d "$fname" ]; then
            cd "$fname"
            $1
            $smake
        else
            cd "$pwd"
            error "$lang_bulid $package"
            exit 1
        fi
    else
        cd "$pwd"
        error "$lang_bulid $package"
        exit 1
    fi
    cd "$pwd"
}

lang() {
    lang_cut=$(echo "$LANG" | awk -F "." '{print $1}')
    case $lang_cut in
    zh_CN)
        lang_install="正在安装"
        lang_bulid="请重新运行脚本或手动编译"
        lang_ver="未找到版本"
        lang_un="未知参数"
        lang_release="找不到/etc/*-release文件，此操作系统可能不支持"
        lang_eros="无法检测到支持的操作系统"
        lang_subu="编译完成，请前往 $pwd 下载 $DIST_DIR.zip"
        lang_exit="用户退出编译"
        lang_num="请输入数字"
        lang_to="到"
        lang_real="该脚本只适用于 $os_real 系统"
        lang_downer="下载失败 $1. 无法继续,请检查您的网络连接和DNS设置"
        lang_downin="正在下载"
        lang_tput="未找到tput,已禁用彩色输出"
        lang_win64="编译 Windows 64 位 Aria2"
        lang_win32="编译 Windows 32 位 Aria2"
        lang_linux="编译 Linux Aria2"
        lang_ex="退出"
        ;;
    *)
        lang_install="Installing"
        lang_bulid="Please rerun the script or bulid manually"
        lang_ver="Version not found"
        lang_un="Unknown parameter"
        lang_release="Could not find /etc/*-release files, which may not be supported by this operating system"
        lang_eros="Unable to detect supported OS"
        lang_subu="Bulid is complete, please go to $pwd to download $DIST_DIR.zip"
        lang_exit="User quit bulid"
        lang_num="Please enter numbers"
        lang_to="to"
        lang_real="This script only works on $os_real systems"
        lang_downer="Download failed $1. Unable to continue, please check your internet connection and DNS settings"
        lang_downin="downloading"
        lang_tput="tput not found, color output disabled"
        lang_win64="Bulid Windows 64 bit Aria2"
        lang_win32="Bulid Windows 32 bit Aria2"
        lang_linux="Bulid Linux Aria2"
        lang_ex="Exit"
        ;;
    esac

}

get_distro() {
    arch="$(uname -m)"
    os=$(uname -o)
    # Make sure we're Linux
    if echo "$os" | grep -iq linux; then
        if [ -f /etc/redhat-release ]; then # RHEL/CentOS
            _os_string_ os_string
            os_string=$(cat /etc/redhat-release)
            isrhel=$(echo "$os_string" | grep 'Red Hat')
            if [ ! -z "$isrhel" ]; then
                os_real='RHEL'
            else
                os_real=$(echo "$os_string" | cut -d' ' -f1) # Doesn't work for Scientific
            fi
            os_type=$(echo "$os_real" | tr '[:upper:]' '[:lower:]')
            os_version=$(echo "$os_string" | grep -o '[0-9\.]*')
            os_major_version=$(echo "$os_version" | cut -d '.' -f1)
        elif [ -f /etc/os-release ]; then # Debian/Ubuntu
            # shellcheck disable=SC1091
            . /etc/os-release
            # shellcheck disable=SC2153
            os_real=$NAME
            os_type=$ID
            os_version=$VERSION_ID
            os_major_version=$(echo "${os_version}" | cut -d'.' -f1)
        else
            printf "%s${RED}$lang_release.${NORMAL}\\n"
            return 1
        fi
    else
        printf "%s${RED}$lang_eros.${NORMAL}\\n"
        return 1
    fi
    if [ -n "$1" ]; then
        case $1 in
        real)
            echo "$os_real"
            ;;
        type)
            echo "$os_type"
            ;;
        version)
            echo "$os_version"
            ;;
        major)
            echo "$os_major_version"
            ;;
        *)
            printf "%s${RED}$lang_un${NORMAL}\\n"
            return 1
            ;;
        esac
    fi
    return 0
}

windows_package() {
    if [ ! -f "$pwd"/package ]; then
        cat >"$pwd"/package <<EOF
make
binutils
autoconf
autopoint
automake
autotools-dev
libtool
pkg-config
git
curl
dpkg-dev
gcc-mingw-w64
g++-mingw-w64
mingw-w64
autopoint
libtool
libcppunit-dev
libxml2-dev
libgcrypt20-dev
lzip
sed
EOF
    fi
}

linux_package() {
    if [ ! -f "$pwd"/package ]; then
        cat >"$pwd"/package <<EOF
make
g++-11
binutils
autoconf
automake
autopoint
autotools-dev
git
curl
dpkg-dev
libcurl4-openssl-dev
libevent-dev
ca-certificates
pkg-config
build-essential
libtool
intltool
libgcrypt20-dev
libssl-dev
libxml2-dev
EOF
    fi
}

apt_install() {
    apt-get update && DEBIAN_FRONTEND="noninteractive"
    while IFS= read -r packages; do
        if [ "$lang_cut" = "zh_CN" ]; then
            Installed=$(apt-cache policy "${packages}" | awk 'NR==2 {print}' | awk -F "：" '{print $2}')
        else
            Installed=$(apt-cache policy "${packages}" | awk 'NR==2 {print}' | awk -F ": " '{print $2}')
        fi
        if [ "$Installed" = "(none)" ] || [ "$Installed" = "(无)" ]; then
            info "$lang_install $packages"
            apt-get install -y "$packages"
        fi
    done <"$pwd"/package
    rm -rf "$pwd"/package
}

BUILD_VER() {
    if [ ! -f "$libpath"/libgmp.a ] && [ ! -f "$libpath"/libgmp.la ]; then
        download https://gmplib.org/download/gmp/gmp-6.1.2.tar.lz
        build_if "./configure \
            --disable-shared \
            --enable-static \
            --prefix=/usr/local/$HOST \
            --host=$HOST \
            --disable-cxx \
            --enable-fat \
            CFLAGS="-mtune=generic -O2 -g0""
    fi

    if [ ! -f "$libpath"/libexpat.a ] && [ ! -f "$libpath"/libexpat.la ]; then
        download http://downloads.sourceforge.net/project/expat/expat/2.4.0/expat-2.4.0.tar.bz2
        build_if "./configure \
            --disable-shared \
            --enable-static \
            --prefix=/usr/local/$HOST \
            --host=$HOST \
            --build=$(dpkg-architecture -qDEB_BUILD_GNU_TYPE)"
    fi

    if [ ! -f "$libpath"/libsqlite3.a ] && [ ! -f "$libpath"/libsqlite3.la ]; then
        download https://www.sqlite.org/2017/sqlite-autoconf-3200100.tar.gz
        build_if "./configure \
            --disable-shared \
            --enable-static \
            --prefix=/usr/local/$HOST \
            --host=$HOST \
            --build=$(dpkg-architecture -qDEB_BUILD_GNU_TYPE)"
    fi

    if [ ! -f "$libpath"/libz.a ]; then
        download http://zlib.net/zlib-1.2.13.tar.gz
        if [ -f "$pwd"/"$package" ]; then
            tar xf "$package"
            if [ -d "$fname" ]; then
                cd "$fname"
                CC=$HOST-gcc \
                    AR=$HOST-ar \
                    LD=$HOST-ld \
                    RANLIB=$HOST-ranlib \
                    STRIP=$HOST-strip \
                    ./configure \
                    --prefix=/usr/local/"$HOST" \
                    --libdir=/usr/local/"$HOST"/lib \
                    --includedir=/usr/local/"$HOST"/include \
                    --static
                $smake
            else
                cd "$pwd"
                error "$lang_bulid $package"
                exit 1
            fi
        else
            cd "$pwd"
            error "$lang_bulid $package"
            exit 1
        fi

    fi

    if [ ! -f "$libpath"/libcares.a ] && [ ! -f "$libpath"/libcares.la ]; then
        download https://c-ares.haxx.se/download/c-ares-1.13.0.tar.gz
        build_if "./configure \
            --disable-shared \
            --enable-static \
            --without-random \
            --prefix=/usr/local/$HOST \
            --host=$HOST \
            --build=$(dpkg-architecture -qDEB_BUILD_GNU_TYPE) \
            LIBS="-lws2_32""
    fi

    if [ ! -f "$libpath"/libssh2.a ] && [ ! -f "$libpath"/libssh2.la ]; then
        download https://www.libssh2.org/download/libssh2-1.10.0.tar.gz
        build_if "./configure \
            --disable-shared \
            --enable-static \
            --prefix=/usr/local/$HOST \
            --host=$HOST \
            --build=$(dpkg-architecture -qDEB_BUILD_GNU_TYPE) \
            --without-openssl \
            --with-wincng \
            LIBS="-lws2_32""
    fi

}

windows_build_aria() {
    if [ ! -d "$pwd"/aria2 ]; then
        git clone https://github.com/aria2/aria2
        cd aria2 && autoreconf -i && HOST=$HOST ./mingw-config && make
    else
        cd aria2 && autoreconf -i && HOST=$HOST ./mingw-config && make
    fi

    if [ -f "$pwd"/aria2/src/aria2c.exe ]; then
        cd "$pwd"/aria2
        . ./script-helper

        get_version

        if [ -z "$VERSION" ]; then
            error "$lang_ver"
            exit 1
        fi

        DIST_DIR=aria2-${VERSION}-${LABEL}-build${BUILD_VER}

        /usr/bin/"$HOST"-strip src/aria2c.exe
        mkdir "$DIST_DIR"
        cp AUTHORS COPYING ChangeLog LICENSE.OpenSSL NEWS README.html README.mingw \
            src/aria2c.exe "$DIST_DIR"
        zip -9 -r "$DIST_DIR".zip "$DIST_DIR"
    fi

    if [ -f "$DIST_DIR".zip ]; then
        cp "$DIST_DIR".zip "$pwd"
        success "$lang_subu"
        rm -rf "$DIST_DIR"
        rmtmp
        chown -R "$USER_NAME" "$pwd"
    fi
}

linux_build_aria() {
    if [ ! -d "$pwd"/aria2 ]; then
        git clone https://github.com/aria2/aria2
        cd aria2 && autoreconf -i && ./configure && make
    else
        cd aria2 && autoreconf -i && ./configure && make
    fi

    if [ -f "$pwd"/aria2/src/aria2c ]; then
        cd $(dirname "$0")
        . ./script-helper

        get_version

        if [ -z "$VERSION" ]; then
            error "$lang_ver"
            exit 1
        fi

        DIST_DIR=aria2-${VERSION}-${LABEL}-build${BUILD_VER}

        /usr/bin/strip src/aria2c
        mkdir "$DIST_DIR"
        cp AUTHORS COPYING ChangeLog LICENSE.OpenSSL NEWS README.html README.mingw \
            src/aria2c "$DIST_DIR"
        tar czvf "$DIST_DIR".tar.gz "$DIST_DIR"
    fi

    if [ -f "$DIST_DIR".tar.gz ]; then
        cp "$DIST_DIR".tar.gz "$pwd"
        success "$lang_subu"
        rm -rf "$DIST_DIR"
        rmtmp
        chown -R "$USER_NAME" "$pwd"
    fi
}
windows_64() {
    test -z "$HOST" && HOST=x86_64-w64-mingw32
    test -z "$BUILD_VER" && BUILD_VER=1
    test -z "$LABEL" && LABEL=$HOST
    libpath=/usr/local/x86_64-w64-mingw32/lib
    mingw32=/usr/x86_64-w64-mingw32
}

windows_32() {
    test -z "$HOST" && HOST=i686-w64-mingw32
    test -z "$BUILD_VER" && BUILD_VER=1
    test -z "$LABEL" && LABEL=$HOST
    libpath=/usr/local/i686-w64-mingw32/lib
    mingw32=/usr/i686-w64-mingw32
}

linux() {
    test -z "$HOST" && HOST=linux
    test -z "$BUILD_VER" && BUILD_VER=1
    test -z "$LABEL" && LABEL=$HOST
}

mkdri_Host() {
    if [ ! -d "$pwd"/"$HOST" ]; then
        mkdir "$pwd"/"$HOST"
        cd "$pwd"/"$HOST"
        pwd=$(pwd)
    else
        cd "$pwd"/"$HOST"
        pwd=$(pwd)
    fi
}
main() {
    if [ "$HOST" = x86_64-w64-mingw32 ] || [ "$HOST" = i686-w64-mingw32 ]; then
        if [ -d "$mingw32" ]; then
            BUILD_VER
            windows_build_aria
        else
            apt_install
            BUILD_VER
            windows_build_aria
        fi
    elif [ "$HOST" = linux ]; then
        apt_install
        linux_build_aria
    fi
}

usage() {
    while read -r num; do
        case $num in
        1)
            windows_64
            mkdri_Host
            windows_package
            main
            exit 0
            ;;
        2)
            windows_32
            mkdri_Host
            windows_package
            main
            exit 0
            ;;
        3)
            linux
            mkdri_Host
            linux_package
            main
            exit 0
            ;;
        4)
            clear
            error "$lang_exit"
            exit 0
            ;;
        *)
            printf "%s\\n${YELLOW}$lang_num ${CYAN}[1]${YELLOW} $lang_to ${CYAN}[4]${YELLOW}:${NORMAL} "
            ;;
        esac
    done
}

lang
get_distro

if [ "$os_real" != Ubuntu ]; then
    error "$lang_real"
    exit
fi

printf "%s${GREEN}1.$lang_win64${NORMAL}\n"
printf "%s${GREEN}2.$lang_win32${NORMAL}\n"
printf "%s${GREEN}3.$lang_linux${NORMAL}\n"
printf "%s${GREEN}4.$lang_ex ${NORMAL}\n"
printf "%s${YELLOW}$lang_num [${CYAN}1${YELLOW}-${CYAN}4${YELLOW}]:${NORMAL}"
usage
